
#include "stdafx.h"
#include "TcpPortTestPassiveConnectionActor.h"
#include "TcpPortTestApp.h"

#define ERROR_SERVERCONNECTIONACTOR_ONREAD_UNEXPECTED_ERROR		-10001
#define ERROR_SERVERCONNECTIONACTOR_ONWRITE_UNEXPECTED_ERROR	-10002

TcpPortTestPassiveConnectionActorMgr::TcpPortTestPassiveConnectionActorMgr( std::size_t _workerPoolSize /*= 1*/ )
    :ActorMgrBase(_workerPoolSize)
{

}

TcpPortTestPassiveConnectionActorMgr::~TcpPortTestPassiveConnectionActorMgr()
{

}

retT TcpPortTestPassiveConnectionActorMgr::makeActor( boost::shared_ptr<ActorBase>& _pActor )
{
    _pActor.reset(new TcpPortTestPassiveConnectionActor());
    R(ActorMgrBase::makeActor(_pActor));
	RETSUCCESS;
}

TcpPortTestPassiveConnectionActor::TcpPortTestPassiveConnectionActor()
{

}

TcpPortTestPassiveConnectionActor::~TcpPortTestPassiveConnectionActor()
{

}

retT TcpPortTestPassiveConnectionActor::start()
{
	R(ActorBase::start());
	if(boost::shared_ptr<WorkerBase> pWorker = getWorker())
	{
		boost::shared_ptr<IoBuffer> pBuffer(new IoBuffer(pWorker));
		boost::shared_ptr<DataHandlerContext> pDataHandlerContext(new DataHandlerContext);
		pDataHandlerContext->bytesToTransfer_ = sizeof(int);
		R(pTcpConnectionHandler->asyncRead(pBuffer, pDataHandlerContext));
	}
	else
		RET(ERROR_COMMON_SHARED_PTR_NULL);
	RETSUCCESS;
}

retT TcpPortTestPassiveConnectionActor::onRead( boost::shared_ptr<DataHandlerContext> _pDataHandlerContext, std::size_t _bytesTransferred, const boost::system::error_code& e, std::size_t _timeoutCount )
{
    R(ITcpAction::onRead(_pDataHandlerContext, _bytesTransferred, e, _timeoutCount));
    if(!e)
    {
        if(_pDataHandlerContext)
        {
            int i;
            R(_pDataHandlerContext->pBuffer_->read(i));
            std::cout << i << std::endl;
            R(_pDataHandlerContext->pBuffer_->seek(0));
			_pDataHandlerContext->bytesToTransfer_ = 0;
            R(pTcpConnectionHandler->asyncWrite(_pDataHandlerContext->pBuffer_, _pDataHandlerContext));
        }
    }
	else if(e == boost::asio::error::eof || e == boost::asio::error::connection_aborted
		|| e == boost::asio::error::connection_reset || e == boost::asio::error::connection_refused
		|| e == boost::asio::error::shut_down)
	{
		LOG_INFO(boost::format( "errorNo %1% : %2% in %3% %4% %5%" ) % e.value() % e.message() % __FUNCTION__ % __FILE__ % __LINE__);
		R(close());
	}
    else
    {
		LOG_ERROR(boost::format( "unexpected error %1% : %2% in %3% %4% %5%" ) % e.value() % e.message() % __FUNCTION__ % __FILE__ % __LINE__);
		RET(ERROR_SERVERCONNECTIONACTOR_ONREAD_UNEXPECTED_ERROR);
    }
    RETSUCCESS;
}

retT TcpPortTestPassiveConnectionActor::onWrite( boost::shared_ptr<DataHandlerContext> _pDataHandlerContext, std::size_t _bytesTransferred, const boost::system::error_code& e, std::size_t _timeoutCount )
{
    R(ITcpAction::onWrite(_pDataHandlerContext, _bytesTransferred, e, _timeoutCount));
    if(!e)
    {
        if(_pDataHandlerContext)
        {
            _pDataHandlerContext->pBuffer_->clear();
            _pDataHandlerContext->bytesToTransfer_ = sizeof(int);
            R(pTcpConnectionHandler->asyncRead(_pDataHandlerContext->pBuffer_, _pDataHandlerContext));
        }
    }
	else if(e == boost::asio::error::eof || e == boost::asio::error::connection_aborted
		|| e == boost::asio::error::connection_reset || e == boost::asio::error::connection_refused
		|| e == boost::asio::error::shut_down)
	{
		LOG_INFO(boost::format( "errorNo %1% : %2% in %3% %4% %5%" ) % e.value() % e.message() % __FUNCTION__ % __FILE__ % __LINE__);
		R(close());
	}
    else
    {
		LOG_ERROR(boost::format( "unexpected error %1% : %2% in %3% %4% %5%" ) % e.value() % e.message() % __FUNCTION__ % __FILE__ % __LINE__);
		RET(ERROR_SERVERCONNECTIONACTOR_ONWRITE_UNEXPECTED_ERROR);
    }
    RETSUCCESS;
}

retT TcpPortTestPassiveConnectionActor::init()
{
	R(ActorBase::init());
	pTcpConnectionHandler.reset(new TcpHandler());
	R(pTcpConnectionHandler->attachHandlerOwner(shared_from_this()));
	RETSUCCESS;
}

boost::shared_ptr<boost::asio::ip::tcp::socket> TcpPortTestPassiveConnectionActor::getTcpSocket()
{
	return pTcpConnectionHandler->getSocket();
}
